package commons
{
	import flash.display.Loader;
	import flash.display.LoaderInfo;
	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.net.URLLoader;
	import flash.net.URLLoaderDataFormat;
	import flash.net.URLRequest;
	import flash.system.ApplicationDomain;
	import flash.system.LoaderContext;
	import flash.utils.ByteArray;
	import flash.utils.Dictionary;

	import events.loader.LocalCacheEvent;

	public class LocalCacheManager extends EventDispatcher
	{
		private static var _instance:LocalCacheManager;
		private var _isLoading:Dictionary;
		private var _urlDic:Dictionary;
		private var _cacheURLloaderList:Array=[];
		private var _loaderContext:LoaderContext;

		public function LocalCacheManager()
		{
			_isLoading=new Dictionary();
			_urlDic=new Dictionary();
			_loaderContext=new LoaderContext();
			_loaderContext.applicationDomain=ApplicationDomain.currentDomain;
			_loaderContext.allowCodeImport=true;
		}

		public static function getInstance():LocalCacheManager
		{
			if (_instance == null)
			{
				_instance=new LocalCacheManager();
			}

			return _instance;
		}

		public function loadFile(url:String, isfirst:Boolean=false):void
		{
			if (url == null)
				return;

			if (_isLoading[url] == true)
				return;
			_isLoading[url]=true;

			var urlLoader:URLLoader=createURLloader();
			_urlDic[urlLoader]=url;
			urlLoader.dataFormat=URLLoaderDataFormat.BINARY;
			urlLoader.addEventListener(Event.COMPLETE, urlLoaderCompelteHandler);
			urlLoader.addEventListener(ProgressEvent.PROGRESS, onProgressHandler);
			urlLoader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
			urlLoader.load(new URLRequest(url));
		}

		private function urlLoaderCompelteHandler(evt:Event):void /////网络数据加载完毕;
		{
			var writeByte:ByteArray;
			var url:String=_urlDic[evt.target];
			var byte:ByteArray=URLLoader(evt.target).data as ByteArray;
			writeByte=new ByteArray();
			writeByte.writeBytes(byte);
			removeLoaderEvent(evt.target);
			var loader:Loader;
			_cacheURLloaderList.push(evt.target);

			switch (url.substr(-2, 2))
			{
				case "wf":
					loader=new Loader();
					_urlDic[loader.contentLoaderInfo]=url;
					loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onCompleteHandler);
					loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
					loader.loadBytes(byte, _loaderContext);
					break;
				case "ng":
					loader=new Loader();
					_urlDic[loader.contentLoaderInfo]=url;
					loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onCompleteHandler);
					loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
					loader.loadBytes(byte, _loaderContext);
					break;
				case "xx":
					// 这个临时字节数组是为了防止原压缩数据被解压之后写入本地缓存导致再次解压无效的问题。
					var tempByteArray:ByteArray=new ByteArray();
					tempByteArray.writeBytes(URLLoader(evt.target).data);
					tempByteArray.position=0;
					var event:LocalCacheEvent=new LocalCacheEvent(Event.COMPLETE, url, tempByteArray);
					dispatchEvent(event);
					delete _isLoading[url];
					break;
				case "pg":
					loader=new Loader();
					_urlDic[loader.contentLoaderInfo]=url;
					loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onCompleteHandler);
					loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
					loader.loadBytes(byte, _loaderContext);
					break;
			}
			byte=null;
			writeByte=null;

		}

		private function onCompleteHandler(evt:Event):void
		{

			var content:Object;
			if (evt.target is LoaderInfo)
			{
				content=LoaderInfo(evt.target).content;
			}
			if (evt.target is URLLoader)
			{
				content=URLLoader(evt.target).data;
			}
			var event:LocalCacheEvent=new LocalCacheEvent(Event.COMPLETE, _urlDic[evt.target], content);
			delete _isLoading[_urlDic[evt.target]];

			dispatchEvent(event);
			removeLoaderEvent(evt.target);
		}

		private function removeLoaderEvent(obj:Object):void
		{
			if (obj is LoaderInfo)
			{
				var loaderInfo:LoaderInfo=obj as LoaderInfo;
				loaderInfo.removeEventListener(ProgressEvent.PROGRESS, onProgressHandler);
				loaderInfo.removeEventListener(Event.COMPLETE, onCompleteHandler);
				loaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
				if (loaderInfo.loader.content is MovieClip)
					MovieClip(loaderInfo.loader.content).stop();
				loaderInfo.loader.unload();
			}
			else if (obj is URLLoader)
			{
				try
				{
					URLLoader(obj).close();
				}
				catch (e:Error)
				{

				}
				URLLoader(obj).removeEventListener(Event.COMPLETE, urlLoaderCompelteHandler);
				URLLoader(obj).removeEventListener(ProgressEvent.PROGRESS, onProgressHandler);
				URLLoader(obj).removeEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
			}
			delete _isLoading[_urlDic[obj]];
			delete _urlDic[obj];
		}

		private function createURLloader():URLLoader
		{
			var urlloader:URLLoader;
			if (_cacheURLloaderList.length)
				urlloader=_cacheURLloaderList.pop();
			else
				urlloader=new URLLoader();
			return urlloader;
		}

		private function ioErrorHandler(evt:IOErrorEvent):void
		{
			trace("资源加载失败：" + _urlDic[evt.target]);
		}

		private function onProgressHandler(evt:ProgressEvent):void
		{
			var event:LocalCacheEvent=new LocalCacheEvent(ProgressEvent.PROGRESS, _urlDic[evt.target], {bytesLoaded: evt.bytesLoaded, bytesTotal: evt.bytesTotal});
			dispatchEvent(event);
		}
	}
}

